//    Copyright (C) Kherty.  All rights reserved.
using System.Collections.Generic;
using System.Windows.Media.Media3D;

namespace OpenLS.Chart.UI
{
    class Tessellator
    {
        

        public static void Tessellate (MeshGeometry3D geometry, Vector3D normal, params Point3D[] points)
        {
            Tessellate(geometry, normal, (IEnumerable <Point3D> )points);
        }

        public static void Tessellate(MeshGeometry3D geometry, Vector3D normal, IEnumerable<Point3D> points)
        {
            int startIndex = geometry.Positions.Count;
            int count = 0;
            foreach (Point3D point in points)
            {
                geometry.Positions.Add(point);
                geometry.Normals.Add(normal);
                count++;
            }
            for (int i = 0; i + 2 < count; i++)
            {
                geometry.TriangleIndices.Add(startIndex);
                geometry.TriangleIndices.Add(startIndex + i + 1);
                geometry.TriangleIndices.Add(startIndex + i + 2);
            }
        }
        public static void TessellateBack(MeshGeometry3D geometry, bool backSide, Vector3D normal, IEnumerable<Point3D> points)
        {
            int startIndex = geometry.Positions.Count;
            int count = 0;
            foreach (Point3D point in points)
            {
                geometry.Positions.Add(point);
                if (backSide)
                    geometry.Normals.Add(-normal);
                else
                geometry.Normals.Add(normal);
                count++;
            }
            if (backSide)
            {
                for (int i = 0; i + 2 < count; i++)
                {
                    geometry.TriangleIndices.Add(startIndex);
                    geometry.TriangleIndices.Add(startIndex + i + 2);
                    geometry.TriangleIndices.Add(startIndex + i + 1);
                }
            }
            else
            {
                for (int i = 0; i + 2 < count; i++)
                {
                    geometry.TriangleIndices.Add(startIndex);
                    geometry.TriangleIndices.Add(startIndex + i + 1);
                    geometry.TriangleIndices.Add(startIndex + i + 2);
                }
                
            }
        }
        public static void TessellateDoubleSide(MeshGeometry3D geometry, Vector3D normal, params Point3D[] points)
        {
            int startIndex = geometry.Positions.Count;
            int count = 0;
            foreach (Point3D point in points)
            {
                geometry.Positions.Add(point);
                geometry.Normals.Add(normal);
                count++;
            }
            for (int i = 0; i + 2 < count; i++)
            {
                geometry.TriangleIndices.Add(startIndex);
                geometry.TriangleIndices.Add(startIndex + i + 1);
                geometry.TriangleIndices.Add(startIndex + i + 2);
            }
            startIndex += count;
            count = 0;
            foreach (Point3D point in points)
            {
                geometry.Positions.Add(point);
                geometry.Normals.Add(-normal);
                count++;
            }
            for (int i = 0; i + 2 < count; i++)
            {
                geometry.TriangleIndices.Add(startIndex);
                geometry.TriangleIndices.Add(startIndex + i + 2);
                geometry.TriangleIndices.Add(startIndex + i + 1);
            }
        }

        internal static void Tessellate(MeshGeometry3D geometry, params Point3D[] points)
        {
            Vector3D normal = Vector3D.CrossProduct(points[1] - points[0], points[2] - points[0]);
            Tessellate(geometry, normal, points);
        }
        internal static void Tessellate(MeshGeometry3D geometry, bool backSide, params Point3D[] points)
        {
            Vector3D normal = Vector3D.CrossProduct(points[1] - points[0], points[2] - points[0]);
                TessellateBack(geometry, backSide, normal, points);
        }

        internal static void TessellateDoubleSide(MeshGeometry3D geometry, params Point3D[] points)
        {
            Vector3D normal = Vector3D.CrossProduct(points[1] - points[0], points[2] - points[0]);
            TessellateDoubleSide(geometry, normal, points);
        }

    }
}
